package com.tang.plugin.ui;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.tang.plugin.Config;
import com.tang.plugin.TemplateConfigurable;
import com.tang.plugin.model.Module;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;

public class CreateModuleDialog extends JDialog {

    private JPanel contentPanel;
    private JPanel panelTitle;
    private JLabel titleLabel;
    private JPanel panelMain;
    private JPanel panelTemplate;
    private JComboBox cbModuleTemplate;
    private JButton btnConfigure;
    private JScrollPane spPlaceHolder;
    private JScrollPane spFileTemplate;
    private EditableTable tablePlaceHolder;
    private EditableTable tableFileTemplate;
    private PreviewPanel panelPreview;
    private JPanel panelNext;
    private JButton btnCancel;
    private JButton btnPrevious;
    private JButton btnNext;

    private List<String> titles = new ArrayList<>();
    private List<JPanel> panels = new ArrayList<>();
    private int currentPanelIndex = 0;

    private List<Module> moduleTemplates = new ArrayList<>();
    private Module selectedModule;

    private OnFinishListener onFinishListener;
    private Project project;

    public CreateModuleDialog(Project project, OnFinishListener onFinishListener) {
        this.project = project;
        this.onFinishListener = onFinishListener;
        setContentPane(contentPanel);
        setModal(true);
        getRootPane().setDefaultButton(btnPrevious);
    }

    public static void showDialog(Project project, OnFinishListener onFinishListener) {
        CreateModuleDialog dialog = new CreateModuleDialog(project, onFinishListener);
        dialog.initView();
        dialog.initData();
        dialog.pack();
        dialog.setVisible(true);
    }

    private void initView() {
        // 设置窗口大小
        Dimension screen = getToolkit().getScreenSize();
        int width = screen.width / 3;
        int height = 600;
        int x = screen.width / 2 - width / 2;
        int y = screen.height / 2 - height / 2;
        setLocation(x, y);
        contentPanel.setPreferredSize(new Dimension(width, height));

        setTitle("Create Module");
        // 点击 X 时调用 onCancel()
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        // 遇到 ESCAPE 时调用 onCancel()
        contentPanel.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        panelPreview = new PreviewPanel();

        cbModuleTemplate.addItemListener((e -> onModuleConfigChange()));

        btnConfigure.setIcon(AllIcons.General.GearPlain);
        btnConfigure.addActionListener(e -> onConfigure());

        tablePlaceHolder = new EditableTable(new String[]{"key", "value"}, new boolean[]{false, true});
        tablePlaceHolder.setToolbarVisible(false);
        spPlaceHolder.setViewportView(tablePlaceHolder);


        tableFileTemplate = new EditableTable(new String[]{"fileName", "template"}, new boolean[]{false, true});
        tableFileTemplate.setToolbarVisible(false);
        spFileTemplate.setViewportView(tableFileTemplate);

        btnCancel.addActionListener(e -> onCancel());
        btnPrevious.addActionListener(e -> onPrevious());
        btnNext.addActionListener(e -> onNext());

        titles.add("Create Module From Template");
        panels.add(panelTemplate);
        titles.add("Preview Module");
        panels.add(panelPreview);

    }

    private void initData() {
        moduleTemplates = Config.loadModuleTemplates();
        List<String> temp = new ArrayList<>();
        moduleTemplates.forEach((module -> temp.add(module.getName())));
        cbModuleTemplate.setModel(new DefaultComboBoxModel<>(temp.toArray()));
        if (cbModuleTemplate.getModel().getSize() > 0) {
            cbModuleTemplate.setSelectedIndex(0);
            onModuleConfigChange();
        }
    }

    private void onModuleConfigChange() {
        selectedModule = moduleTemplates.get(cbModuleTemplate.getSelectedIndex());
        panelPreview.setModuleConfigPreview(selectedModule);
        tablePlaceHolder.setPairData(selectedModule.getTemplate().getAllPlaceHolderMap());
        tableFileTemplate.setPairData(selectedModule.getTemplate().getAllFileTemplateMap());
    }

    private void onConfigure() {
        ShowSettingsUtil.getInstance().editConfigurable(project, new TemplateConfigurable(this::initData));
    }

    private void onCancel() {
        dispose();
    }

    private void onPrevious() {
        if (currentPanelIndex == 0) {
            return;
        }
        currentPanelIndex--;
        changePanel();
        changeButton();
    }

    private void onNext() {
        selectedModule.getTemplate().setPlaceHolderMap(tablePlaceHolder.getPairResult());
        selectedModule.getTemplate().setFileTemplate(tableFileTemplate.getPairResult());
        panelPreview.setModuleConfigPreview(selectedModule);

        if (currentPanelIndex == panels.size() - 1) {
            onFinish();
            dispose();
            return;
        }

        currentPanelIndex++;
        changePanel();
        changeButton();
    }

    private void onFinish() {
        if (onFinishListener != null) {
            onFinishListener.onFinish(selectedModule);
        }
    }

    private void changePanel() {
        titleLabel.setText(titles.get(currentPanelIndex));
        panelMain.removeAll();
        panelMain.add(panels.get(currentPanelIndex));
        panelMain.doLayout();
        panelMain.updateUI();
    }

    private void changeButton() {
        btnPrevious.setEnabled(true);
        btnNext.setText("Next");
        if (currentPanelIndex == titles.size() - 1) {
            btnNext.setText("Finish");
        } else if (currentPanelIndex == 0) {
            btnPrevious.setEnabled(false);
        }
    }

    public interface OnFinishListener {
        void onFinish(Module config);
    }

}
